package com.hbnu.service;

import com.hbnu.dao.FunctionDao;
import com.hbnu.entity.User;
import com.hbnu.entity.UserFile;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

import static com.hbnu.tools.PrintTool.*;
import static com.hbnu.tools.ScannerTool.nextLine;
import static com.hbnu.web.Manage.*;

public class FunctionService {
    //
    public final Set<String> cmdSet;
    public final Map<String,Runnable> cmdMap;
    public final Map<String, Consumer<String>> oneMap;
    public final Map<String, BiConsumer<String,String>> twoMap;
    private final FunctionDao functionDao;
    private final FileService fileService;

    public FunctionService() {
        //文件操作
        fileService =new FileService();
        //数据库操作
        functionDao=new FunctionDao();
        //指令
        cmdMap=new HashMap<>();
        oneMap=new HashMap<>();
        twoMap=new HashMap<>();


        cmdMap.put("clear",this::clear);
        cmdMap.put("exit",this::exit);

        oneMap.put("ls",this::ls);
        oneMap.put("close",this::close);
        oneMap.put("start",this::start);
        oneMap.put("delete",this::delete);
        oneMap.put("rollback",this::rollback);

        twoMap.put("delete",this::delete);
        twoMap.put("add",this::add);

        cmdSet=new HashSet<>();
        cmdSet.addAll(cmdMap.keySet());
        cmdSet.addAll(oneMap.keySet());
        cmdSet.addAll(twoMap.keySet());
    }

    private void exit() {
        fileService.close();
        println("Bye");
        System.exit(0);
    }

    private int StringToInt(String id){
        try {
            return Integer.parseInt(id);
        }catch (Exception e){
            throw new RuntimeException("输入结果非整数！");
        }
    }

    //ls user
    //ls file
    private void ls(String s) {
        if("user".equals(s)){
            printUserList(userMap);
        }else if("file".equals(s)){
            List<UserFile> userFileList=functionDao.selectUserFileDeleted();
            //空的 直接查
            if(null==userFileList){
               println("查询异常！");return;
            }
            if(userFileList.isEmpty()) return;
            printUserFileList(userFileList);
        }
    }
    //恢复号
    //start id
    private void start(String id) {
        int i = StringToInt(id);
        if(userMap.containsKey(i)){
            functionDao.updateUserDeleted(userMap.get(i).getUid(),0);
            userMap.get(i).setIs_deleted(false);
        }
    }
    //封号
    private void close(String id) {
        int i = StringToInt(id);
        if(userMap.containsKey(i)){
            functionDao.updateUserDeleted(userMap.get(i).getUid(),1);
            userMap.get(i).setIs_deleted(true);
        }
    }
    //增加空间 add id xG
    private void add(String id, String space) {
        int i = StringToInt(id);
        int size = StringToInt(space);
        if(userMap.containsKey(i)){
            functionDao.addUserSpace(userMap.get(i).getUid(),size);
        }
    }
    //清除所有剩余文件 clear
    // 删除文件记录 delete userfile
    //删除服务器文件 delete file

    private void clear() {
        deleteUserFile();
        deleteServerFile();
    }


    private void delete(String s) {
        if ("userfile".equals(s)){
            //询问是否删除
            deleteUserFile();
        }else if("file".equals(s)){
            //删除服务器文件信息
            deleteServerFile();
        }
    }

    private void deleteUserFile() {
        print("是否删除用户文件记录(y/n): ");
        if(nextLine().equalsIgnoreCase("Y")) {
            functionDao.deleteUserFile();
        }
    }
    private void deleteServerFile() {
        Map<Integer,String> map=functionDao.getUselessFilesId();
        if(map.isEmpty()) return;
        print("是否删除服务器文件信息(y/n): ");
        if(nextLine().equalsIgnoreCase("Y")) {
            if(functionDao.deleteServerFile(map.keySet())){
                boolean ok=false;
                try {
                    ArrayList<String> arrays=new ArrayList<>(map.values());
                    //通知服务器删除
                    fileService.deleteFile(arrays);
                    ok=true;
                    println("删除成功！");
                }finally {
                    functionDao.deleteOver(ok);
                }
            }
        }
    }

    //删除用户所有信息 delete user id
    private void delete(String s, String id) {
        if("user".equals(s)){
            int i = StringToInt(id);
            if(userMap.containsKey(i)){
                //删除用户 删除用户文件夹
                functionDao.deleteUser(userMap.get(i));
                userMap.remove(i);
            }
        }
    }

    //回滚该用户所有删除  rollback
    private void rollback(String id) {
        int i = StringToInt(id);
        if(userMap.containsKey(i)) {
            User u = userMap.get(i);
            Map<Integer, UserFile> idUserFileMap=functionDao.selectUserFileDeleted(u.getUid());
            //无文件
            if(idUserFileMap.isEmpty()){
                println("无文件！");
                return;
            }
            //将不存在的根文件改为当前
            UserFile root =new UserFile(0);
            root.setFname("~");
            root.setPath("~");
            List<Integer> childList=new ArrayList<>();
            //删除id
            List<Integer> ids=new ArrayList<>();
            idUserFileMap.put(0,root);
            for(Integer integer:idUserFileMap.keySet()){
                UserFile userFile = idUserFileMap.get(integer);
                //空根
                if(null==userFile.getFname()){
                    //处理子内容
                  if(userFile.hasChildren()){
                      List<Integer> list = userFile.getList();
                      //子内容的id进行修改
                      for (Integer integer1 : list) {
                          idUserFileMap.get(integer1).setPid(0);
                      }
                      //子内容添加到新list下
                      childList.addAll(list);
                  }
                  //删除原id
                    ids.add(integer);
                }
            }
            //删除原id
            for (Integer integer : ids) {
             idUserFileMap.remove(integer);
            }
            root.setList(childList);

            //查看删除文件树
            printDeleteTree(root,idUserFileMap);
            //对文件进行恢复
            print("输入恢复id: ");
            String s = nextLine();
            int fid = StringToInt(s);
            if(fid==0||!idUserFileMap.containsKey(fid)){
                println("id不存在！");
                return;
            }
            //检查大小
            long size=getFSize(fid,idUserFileMap);
            if(size==-1){
                println("查询异常！");
                return;
            }
            if(u.getSpace()-u.getSize()<size){
                println("文件大小: "+formatFileSize(size)+" 用户空间不足无法恢复!");
                return;
            }
            //进行恢复 恢复至文件root
            functionDao.rollback(u.getUid(),u.getFid(),fid,size);
            println("恢复成功");
        }
    }


    private long getFSize(int fid,Map<Integer, UserFile> idUserFileMap) {
        List<Integer> fileIdList= getFileIdList(fid,idUserFileMap);
        long size=0;
        if (!fileIdList.isEmpty())  size = functionDao.sumFileSize(fileIdList);
        return size;
    }


    //获得文件下的文件id
    private List<Integer> getFileIdList(int fid,Map<Integer, UserFile> idUserFileMap){
        List<Integer> list=new ArrayList<>();
        Queue<Integer> queue=new LinkedList<>();
        queue.add(fid);
        while (!queue.isEmpty()){
            fid=queue.poll();
            UserFile userFile = idUserFileMap.get(fid);
            if(userFile.is_file()){
                list.add(userFile.getFile_id());
            }else if(userFile.hasChildren()){
                queue.addAll(userFile.getList());
            }
        }
        return list;
    }

}
